package com.itheima.huikebackend.service.impl;

import com.itheima.huikebackend.entity.SysMenu;
import com.itheima.huikebackend.mapper.SysMenuMapper;

import com.itheima.huikebackend.service.SysMenuService;
import com.itheima.huikebackend.utils.AuthUtils;
import com.itheima.huikebackend.vo.MetaVO;
import com.itheima.huikebackend.vo.RouterVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl implements SysMenuService {

    private final SysMenuMapper sysMenuMapper;

    @Override
    public List<RouterVO> selectTreeMenu(String currentId) {

        List<SysMenu> sysMenus;
        if (AuthUtils.isAdmin(Integer.valueOf(currentId))) {
            sysMenus = sysMenuMapper.selectAll();
        } else {
            sysMenus = sysMenuMapper.selectAllByUserId(currentId);
        }

        // 生成树结构
        List<SysMenu> sysMenus1 = buildDeptTreeByStream(sysMenus);

        // 将树结构根据前端需要的格式进行格式化
        return formatRouter(sysMenus1);
    }


    /**
     * 构建树结构
     * @param trees
     * @return
     */
    public List<SysMenu> buildDeptTreeByStream(List<SysMenu> trees){
        //获取parentId = 0的根节点
        List<SysMenu> list = trees.stream().filter(item -> item.getParentId() == 0L).collect(Collectors.toList());
        //根据parentId进行分组
        Map<Long, List<SysMenu>> map = trees.stream().collect(Collectors.groupingBy(SysMenu::getParentId));
        recursionFnTree(list, map);
        return list;
    }

    /**
     * 递归遍历节点
     * @param list
     * @param map
     */
    public void recursionFnTree(List<SysMenu> list, Map<Long, List<SysMenu>> map){
        for (SysMenu treeSelect : list) {
            List<SysMenu> childList = map.get(treeSelect.getMenuId());
            treeSelect.setChildren(childList);
            if (null != childList && !childList.isEmpty()){
                recursionFnTree(childList,map);
            }
        }
    }

    public List<RouterVO> formatRouter(List<SysMenu> sysMenus) {
        List<RouterVO> routerVOList = new ArrayList<>();
        for (SysMenu menu : sysMenus) {
            RouterVO routerVO = new RouterVO();
            routerVO.setName(getRouterName(menu));
            routerVO.setPath(getRouterPath(menu));
            // 判断visible值是否为1，1就是隐藏，反之则是显示
            routerVO.setHidden("1".equals(menu.getVisible()));
            routerVO.setComponent(getComponent(menu));
            routerVO.setMeta(new MetaVO(menu.getMenuName(), menu.getIcon(), "1".equals(String.valueOf(menu.getIsCache()))));
            List<SysMenu> cMenus = menu.getChildren();
            if (Objects.isNull(cMenus)) {
                cMenus = new ArrayList<>();
            }
            if (!cMenus.isEmpty() && cMenus.size() > 0 && "M".equals(menu.getMenuType())){
                routerVO.setAlwaysShow(true);
                routerVO.setRedirect("noRedirect");
                routerVO.setChildren(formatRouter(cMenus));
            }
            else if (isMenuFrame(menu))
            {
                List<RouterVO> childrenList = new ArrayList<>();
                RouterVO children = new RouterVO();
                children.setPath(menu.getPath());
                children.setComponent(menu.getComponent());
                children.setName(StringUtils.capitalize(menu.getPath()));
                children.setMeta(new MetaVO(menu.getMenuName(), menu.getIcon(), "1".equals(String.valueOf(menu.getIsCache()))));
                childrenList.add(children);
                routerVO.setChildren(childrenList);
            }
            routerVOList.add(routerVO);
        }
        
        return routerVOList;
    }

    /**
     * 获取路由地址
     *
     * @param menu 菜单信息
     * @return 路由地址
     */
    public String getRouterPath(SysMenu menu) {
        String routerPath = menu.getPath();
        // 非外链并且是一级目录（类型为目录）
        if (0 == menu.getParentId().intValue() && "M".equals(menu.getMenuType())
                && "1".equals(String.valueOf(menu.getIsFrame()))) {
            routerPath = "/" + menu.getPath();
        }
        // 非外链并且是一级目录（类型为菜单）
        else if (isMenuFrame(menu)) {
            routerPath = "/";
        }
        return routerPath;
    }

    /**
     * 获取路由名称
     * @param menu
     * @return
     */
    private String getRouterName(SysMenu menu) {
        String roterName = StringUtils.capitalize(menu.getPath());
        if (isMenuFrame(menu)) {
            roterName = "";
        }
        return roterName;
    }

    /**
     * 是否为菜单内部跳转
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isMenuFrame(SysMenu menu) {
        return menu.getParentId().intValue() == 0 && "C".equals(menu.getMenuType()) && "1".equals(String.valueOf(menu.getIsFrame()));
    }

    /**
     * 获取组件信息
     *
     * @param menu 菜单信息
     * @return 组件信息
     */
    public String getComponent(SysMenu menu) {
        String component = "Layout";
        if (StringUtils.hasLength(menu.getComponent()) && !isMenuFrame(menu)) {
            component = menu.getComponent();
        } else if (!StringUtils.hasLength(menu.getComponent()) && isParentView(menu)) {
            component = "ParentView";
        }
        return component;
    }

    /**
     * 是否为parent_view组件
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isParentView(SysMenu menu) {
        return menu.getParentId().intValue() != 0 && "M".equals(menu.getMenuType());
    }

}


